// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Net;
using NUnit.Framework;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;

namespace osu.Game.Tests.Visual.Online
{
    public class TestSceneWikiOverlay : OsuTestScene
    {
        private DummyAPIAccess dummyAPI => (DummyAPIAccess)API;

        private WikiOverlay wiki;

        [SetUp]
        public void SetUp() => Schedule(() => Child = wiki = new WikiOverlay());

        [Test]
        public void TestMainPage()
        {
            setUpWikiResponse(responseMainPage);
            AddStep("Show Main Page", () => wiki.Show());
        }

        [Test]
        public void TestArticlePage()
        {
            setUpWikiResponse(responseArticlePage);
            AddStep("Show Article Page", () => wiki.ShowPage("Article_styling_criteria/Formatting"));
        }

        [Test]
        public void TestErrorPage()
        {
            setUpWikiResponse(null, true);
            AddStep("Show Error Page", () => wiki.ShowPage("Error"));
        }

        private void setUpWikiResponse(APIWikiPage r, bool isFailed = false)
            => AddStep("set up response", () =>
            {
                dummyAPI.HandleRequest = request =>
                {
                    if (!(request is GetWikiRequest getWikiRequest))
                        return false;

                    if (isFailed)
                        getWikiRequest.TriggerFailure(new WebException());
                    else
                        getWikiRequest.TriggerSuccess(r);

                    return true;
                };
            });

        // From https://osu.ppy.sh/api/v2/wiki/en/Main_Page
        private APIWikiPage responseMainPage => new APIWikiPage
        {
            Title = "Main Page",
            Layout = "main_page",
            Path = "Main_Page",
            Locale = "en",
            Subtitle = null,
            Markdown =
                "---\nlayout: main_page\n---\n\n<!-- Do not add any empty lines inside this div. -->\n\n<div class=\"wiki-main-page__blurb\">\nWelcome to the osu! wiki, a project containing a wide range of osu! related information.\n</div>\n\n<div class=\"wiki-main-page__panels\">\n<div class=\"wiki-main-page-panel wiki-main-page-panel--full\">\n\n# Getting started\n\n[Welcome](/wiki/Welcome) • [Installation](/wiki/Installation) • [Registration](/wiki/Registration) • [Help Centre](/wiki/Help_Centre) • [FAQ](/wiki/FAQ)\n\n</div>\n<div class=\"wiki-main-page-panel\">\n\n# Game client\n\n[Interface](/wiki/Interface) • [Options](/wiki/Options) • [Visual settings](/wiki/Visual_Settings) • [Shortcut key reference](/wiki/Shortcut_key_reference) • [Configuration file](/wiki/osu!_Program_Files/User_Configuration_File) • [Program files](/wiki/osu!_Program_Files)\n\n[File formats](/wiki/osu!_File_Formats): [.osz](/wiki/osu!_File_Formats/Osz_(file_format)) • [.osk](/wiki/osu!_File_Formats/Osk_(file_format)) • [.osr](/wiki/osu!_File_Formats/Osr_(file_format)) • [.osu](/wiki/osu!_File_Formats/Osu_(file_format)) • [.osb](/wiki/osu!_File_Formats/Osb_(file_format)) • [.db](/wiki/osu!_File_Formats/Db_(file_format))\n\n</div>\n<div class=\"wiki-main-page-panel\">\n\n# Gameplay\n\n[Game modes](/wiki/Game_mode): [osu!](/wiki/Game_mode/osu!) • [osu!taiko](/wiki/Game_mode/osu!taiko) • [osu!catch](/wiki/Game_mode/osu!catch) • [osu!mania](/wiki/Game_mode/osu!mania)\n\n[Beatmap](/wiki/Beatmap) • [Hit object](/wiki/Hit_object) • [Mods](/wiki/Game_modifier) • [Score](/wiki/Score) • [Replay](/wiki/Replay) • [Multi](/wiki/Multi)\n\n</div>\n<div class=\"wiki-main-page-panel\">\n\n# [Beatmap editor](/wiki/Beatmap_Editor)\n\nSections: [Compose](/wiki/Beatmap_Editor/Compose) • [Design](/wiki/Beatmap_Editor/Design) • [Timing](/wiki/Beatmap_Editor/Timing) • [Song setup](/wiki/Beatmap_Editor/Song_Setup)\n\nComponents: [AiMod](/wiki/Beatmap_Editor/AiMod) • [Beat snap divisor](/wiki/Beatmap_Editor/Beat_Snap_Divisor) • [Distance snap](/wiki/Beatmap_Editor/Distance_Snap) • [Menu](/wiki/Beatmap_Editor/Menu) • [SB load](/wiki/Beatmap_Editor/SB_Load) • [Timelines](/wiki/Beatmap_Editor/Timelines)\n\n[Beatmapping](/wiki/Beatmapping) • [Difficulty](/wiki/Beatmap/Difficulty) • [Mapping techniques](/wiki/Mapping_Techniques) • [Storyboarding](/wiki/Storyboarding)\n\n</div>\n<div class=\"wiki-main-page-panel\">\n\n# Beatmap submission and ranking\n\n[Submission](/wiki/Submission) • [Modding](/wiki/Modding) • [Ranking procedure](/wiki/Beatmap_ranking_procedure) • [Mappers' Guild](/wiki/Mappers_Guild) • [Project Loved](/wiki/Project_Loved)\n\n[Ranking criteria](/wiki/Ranking_Criteria): [osu!](/wiki/Ranking_Criteria/osu!) • [osu!taiko](/wiki/Ranking_Criteria/osu!taiko) • [osu!catch](/wiki/Ranking_Criteria/osu!catch) • [osu!mania](/wiki/Ranking_Criteria/osu!mania)\n\n</div>\n<div class=\"wiki-main-page-panel\">\n\n# Community\n\n[Tournaments](/wiki/Tournaments) • [Skinning](/wiki/Skinning) • [Projects](/wiki/Projects) • [Guides](/wiki/Guides) • [osu!dev Discord server](/wiki/osu!dev_Discord_server) • [How you can help](/wiki/How_You_Can_Help!) • [Glossary](/wiki/Glossary)\n\n</div>\n<div class=\"wiki-main-page-panel\">\n\n# People\n\n[The Team](/wiki/People/The_Team): [Developers](/wiki/People/The_Team/Developers) • [Global Moderation Team](/wiki/People/The_Team/Global_Moderation_Team) • [Support Team](/wiki/People/The_Team/Support_Team) • [Nomination Assessment Team](/wiki/People/The_Team/Nomination_Assessment_Team) • [Beatmap Nominators](/wiki/People/The_Team/Beatmap_Nominators) • [osu! Alumni](/wiki/People/The_Team/osu!_Alumni) • [Project Loved Team](/wiki/People/The_Team/Project_Loved_Team)\n\nOrganisations: [osu! UCI](/wiki/Organisations/osu!_UCI)\n\n[Community Contributors](/wiki/People/Community_Contributors) • [Users with unique titles](/wiki/People/Users_with_unique_titles)\n\n</div>\n<div class=\"wiki-main-page-panel\">\n\n# For developers\n\n[API](/wiki/osu!api) • [Bot account](/wiki/Bot_account) • [Brand identity guidelines](/wiki/Brand_identity_guidelines)\n\n</div>\n<div class=\"wiki-main-page-panel\">\n\n# About the wiki\n\n[Sitemap](/wiki/Sitemap) • [Contribution guide](/wiki/osu!_wiki_Contribution_Guide) • [Article styling criteria](/wiki/Article_Styling_Criteria) • [News styling criteria](/wiki/News_Styling_Criteria)\n\n</div>\n</div>\n",
        };

        // From https://osu.ppy.sh/api/v2/wiki/en/Article_styling_criteria/Formatting
        private APIWikiPage responseArticlePage => new APIWikiPage
        {
            Title = "Formatting",
            Layout = "markdown_page",
            Path = "Article_styling_criteria/Formatting",
            Locale = "en",
            Subtitle = "Article styling criteria",
            Markdown =
                "# Formatting\n\n*For the writing standards, see: [Article style criteria/Writing](../Writing)*\n\n*Notice: This article uses [RFC 2119](https://tools.ietf.org/html/rfc2119 \"IETF Tools\") to describe requirement levels.*\n\n## Locales\n\nListed below are the properly-supported locales for the wiki:\n\n| File Name | Locale Name | Native Script |\n| :-- | :-- | :-- |\n| `en.md` | English | English |\n| `ar.md` | Arabic | اَلْعَرَبِيَّةُ |\n| `be.md` | Belarusian | Беларуская мова |\n| `bg.md` | Bulgarian | Български |\n| `cs.md` | Czech | Česky |\n| `da.md` | Danish | Dansk |\n| `de.md` | German | Deutsch |\n| `gr.md` | Greek | Ελληνικά |\n| `es.md` | Spanish | Español |\n| `fi.md` | Finnish | Suomi |\n| `fr.md` | French | Français |\n| `hu.md` | Hungarian | Magyar |\n| `id.md` | Indonesian | Bahasa Indonesia |\n| `it.md` | Italian | Italiano |\n| `ja.md` | Japanese | 日本語 |\n| `ko.md` | Korean | 한국어 |\n| `nl.md` | Dutch | Nederlands |\n| `no.md` | Norwegian | Norsk |\n| `pl.md` | Polish | Polski |\n| `pt.md` | Portuguese | Português |\n| `pt-br.md` | Brazilian Portuguese | Português (Brasil) |\n| `ro.md` | Romanian | Română |\n| `ru.md` | Russian | Русский |\n| `sk.md` | Slovak | Slovenčina |\n| `sv.md` | Swedish | Svenska |\n| `th.md` | Thai | ไทย |\n| `tr.md` | Turkish | Türkçe |\n| `uk.md` | Ukrainian | Українська мова |\n| `vi.md` | Vietnamese | Tiếng Việt |\n| `zh.md` | Chinese (Simplified) | 简体中文 |\n| `zh-tw.md` | Traditional Chinese (Taiwan) | 繁體中文（台灣） |\n\n*Note: The website will give readers their selected language's version of an article. If it is not available, the English version will be given.*\n\n### Content parity\n\nTranslations are subject to strict content parity with their English article, in the sense that they must have the same message, regardless of grammar and syntax. Any changes to the translations' meanings must be accompanied by equivalent changes to the English article.\n\nThere are some cases where the content is allowed to differ:\n\n- Articles originally written in a language other than English (in this case, English should act as the translation)\n- Explanations of English words that are common terms in the osu! community\n- External links\n- Tags\n- Subcommunity-specific explanations\n\n## Front matter\n\nFront matter must be placed at the very top of the file. It is written in [YAML](https://en.wikipedia.org/wiki/YAML#Example \"YAML Wikipedia article\") and describes additional information about the article. This must be surrounded by three hyphens (`---`) on the lines above and below it, and an empty line must follow it before the title heading.\n\n### Articles that need help\n\n*Note: Avoid translating English articles with this tag. In addition to this, this tag should be added when the translation needs its own clean up.*\n\nThe `needs_cleanup` tag may be added to articles that need rewriting or formatting help. It is also acceptable to open an issue on GitHub for this purpose. This tag must be written as shown below:\n\n```yaml\nneeds_cleanup: true\n```\n\nWhen adding this tag to an article, [comments](#comments) should also be added to explain what needs to be done to remove the tag.\n\n### Outdated articles\n\n*Note: Avoid translating English articles with this tag. If the English article has this tag, the translation must also have this tag.*\n\nTranslated articles that are outdated must use the `outdated` tag when the English variant is updated. English articles may also become outdated when the content they contain is misleading or no longer relevant. This tag must be written as shown below:\n\n```yaml\noutdated: true\n```\n\nWhen adding this tag to an article, [comments](#comments) should also be added to explain what needs to be updated to remove the tag.\n\n### Tagging articles\n\nTags help the website's search engine query articles better. Tags should be written in the same language as the article and include the original list of tags. Tags should use lowercase letters where applicable.\n\nFor example, an article called \"Beatmap discussion\" may include the following tags:\n\n```yaml\ntags:\n  - beatmap discussions\n  - modding V2\n  - MV2\n```\n\n### Translations without reviews\n\n*Note: Wiki maintainers will determine and apply this mark prior to merging.*\n\nSometimes, translations are added to the wiki without review from other native speakers of the language. In this case, the `no_native_review` mark is added to let future translators know that it may need to be checked again. This tag must be written as shown below:\n\n```yaml\nno_native_review: true\n```\n\n## Article naming\n\n*See also: [Folder names](#folder-names) and [Titles](#titles)*\n\nArticle titles should be singular and use sentence case. See [Wikipedia's naming conventions article](https://en.wikipedia.org/wiki/Wikipedia:Naming_conventions_(plurals) \"Wikipedia\") for more details.\n\nArticle titles should match the folder name it is in (spaces may replace underscores (`_`) where appropriate). If the folder name changes, the article title should be changed to match it and vice versa.\n\n---\n\nContest and tournament articles are an exception. The folder name must use abbreviations, acronyms, or initialisms. The article's title must be the full name of the contest or tournament.\n\n## Folder and file structure\n\n### Folder names\n\n*See also: [Article naming](#article-naming)*\n\nFolder names must be in English and use sentence case.\n\nFolder names must only use these characters:\n\n- uppercase and lowercase letters\n- numbers\n- underscores (`_`)\n- hyphens (`-`)\n- exclamation marks (`!`)\n\n### Article file names\n\nThe file name of an article can be found in the `File Name` column of the [locales section](#locales). The location of a translated article must be placed in the same folder as the English article.\n\n### Index articles\n\nAn index article must be created if the folder is intended to only hold other articles. Index articles must contain a list of articles that are inside its own folder. They may also contain other information, such as a lead paragraph or descriptions of the linked articles.\n\n### Disambiguation articles\n\n[Disambiguation](/wiki/Disambiguation) articles must be placed in the `/wiki/Disambiguation` folder. The main page must be updated to include the disambiguation article. Refer to [Disambiguation/Mod](/wiki/Disambiguation/Mod) as an example.\n\nRedirects must be updated to have the ambiguous keyword(s) redirect to the disambiguation article.\n\nArticles linked from a disambiguation article must have a [For other uses](#for-other-uses) hatnote.\n\n## HTML\n\nHTML must not be used, with exception for [comments](#comments). The structure of the article must be redone if HTML is used.\n\n### Comments\n\nHTML comments should be used for marking to-dos, but may also be used to annotate text. They should be on their own line, but can be placed inline in a paragraph. If placed inline, the start of the comment must not have a space.\n\nBad example:\n\n```markdown\nHTML comments <!-- TODO explain HTML comments --> should be used for marking to-dos or annotate text.\n```\n\nGood example:\n\n```markdown\nHTML comments<!-- TODO explain HTML comments --> should be used for marking to-dos or annotate text.\n```\n\n## Editing\n\n### End of line sequence\n\n*Caution: Uploading Markdown files using `CRLF` (carriage return and line feed) via GitHub will result in those files using `CRLF`. To prevent this, set the line ending to `LF` (line feed) before uploading.*\n\nMarkdown files must be checked in using the `LF` end of line sequence.\n\n### Escaping\n\nMarkdown syntax should be escaped as needed. However, article titles are parsed as plain text and so must not be escaped.\n\n### Paragraphs\n\nEach paragraph must be followed by one empty line.\n\n### Line breaks\n\nLine breaks must use a backslash (`\\`).\n\nLine breaks must be used sparingly.\n\n## Hatnote\n\n*Not to be confused with [Notice](#notice).*\n\nHatnotes are short notes placed at the top of an article or section to help readers navigate to related articles or inform them about related topics.\n\nHatnotes must be italicised and be placed immediately after the heading. If multiple hatnotes are used, they must be on the same paragraph separated with a line break.\n\n### Main page\n\n*Main page* hatnotes direct the reader to the main article of a topic. When this hatnote is used, it implies that the section it is on is a summary of what the linked page is about. This hatnote should have only one link. These must be formatted as follows:\n\n```markdown\n*Main page: {article}*\n\n*Main pages: {article} and {article}*\n```\n\n### See also\n\n*See also* hatnotes suggest to readers other points of interest from a given article or section. These must be formatted as follows:\n\n```markdown\n*See also: {article}*\n\n*See also: {article} and {article}*\n```\n\n### For see\n\n*For see* hatnotes are similar to *see also* hatnotes, but are generally more descriptive and direct. This hatnote may use more than one link if necessary. These must be formatted as follows:\n\n```markdown\n*For {description}, see: {article}`*\n\n*For {description}, see: {article} and {article}`*\n```\n\n### Not to be confused with\n\n*Not to be confused with* hatnotes help distinguish ambiguous or misunderstood article titles or sections. This hatnote may use more than one link if necessary. These must be formatted as follows:\n\n```markdown\n*Not to be confused with {article}.*\n\n*Not to be confused with {article} or {article}.*\n```\n\n### For other uses\n\n*For other uses* hatnotes are similar to *not to be confused with* hatnotes, but links directly to the [disambiguation article](#disambiguation-articles). This hatnote must only link to the disambiguation article. These must be formatted as follows:\n\n```markdown\n*For other uses, see {disambiguation article}.*\n```\n\n## Notice\n\n*Not to be confused with [Hatnote](#hatnote).*\n\nA notice should be placed where appropriate in a section, but must start off the paragraph and use italics. Notices may contain bolding where appropriate, but should be kept to a minimum. Notices must be written as complete sentences. Thus, unlike most [hatnotes](#hatnotes), must use a full stop (`.`) or an exclamation mark (`!`) if appropriate. Anything within the same paragraph of a notice must also be italicised. These must be formatted as follows:\n\n```markdown\n*Note: {note}.*\n\n*Notice: {notice}.*\n\n*Caution: {caution}.*\n\n*Warning: {warning}.*\n```\n\n- `Note` should be used for factual or trivial details.\n- `Notice` should be used for reminders or to draw attention to something that the reader should be made aware of.\n- `Caution` should be used to warn the reader to avoid unintended consequences.\n- `Warning` should be used to warn the reader that action may be taken against them.\n\n## Emphasising\n\n### Bold\n\nBold must use double asterisks (`**`).\n\nLead paragraphs may bold the first occurrence of the article's title.\n\n### Italics\n\nItalics must use single asterisks (`*`).\n\nNames of work or video games should be italicised. osu!—the game—is exempt from this.\n\nThe first occurrence of an abbreviation, acronym, or initialism may be italicised.\n\nItalics may also be used to provide emphasis or help with readability.\n\n## Headings\n\nAll headings must use sentence case.\n\nHeadings must use the [ATX (hash) style](https://github.github.com/gfm/#atx-headings \"GitHub\") and must have an empty line before and after the heading. The title heading is an exception when it is on the first line. If this is the case, there only needs to be an empty line after the title heading.\n\nHeadings must not exceed a heading level of 5 and must not be used to style or format text.\n\n### Titles\n\n*See also: [Article naming](#article-naming)*\n\n*Caution: Titles are parsed as plain text; they must not be escaped.*\n\nThe first heading in all articles must be a level 1 heading, being the article's title. All headings afterwards must be [section headings](#sections). Titles must not contain formatting, links, or images.\n\nThe title heading must be on the first line, unless [front matter](#front-matter) is being used. If that is the case, the title heading must go after it and have an empty line before the title heading.\n\n### Sections\n\nSection headings must use levels 2 to 5. The section heading proceeding the [title heading](#titles) must be a level 2 heading. Unlike titles, section headings may have small image icons.\n\nSection headings must not skip a heading level (i.e. do not go from a level 2 heading to a level 4 heading) and must not contain formatting or links.\n\n*Notice: On the website, heading levels 4 and 5 will not appear in the table of contents. They cannot be linked to directly either.*\n\n## Lists\n\nLists should not go over 4 levels of indentation and should not have an empty line in between each item.\n\nFor nested lists, bullets or numbers must align with the item content of their parent lists.\n\nThe following example was done incorrectly (take note of the spacing before the bullet):\n\n```markdown\n1. Fly a kite\n  - Don't fly a kite if it's raining\n```\n\nThe following example was done correctly:\n\n```markdown\n1. Fly a kite\n   - Don't fly a kite if it's raining\n```\n\n### Bulleted\n\nBulleted lists must use a hyphen (`-`). These must then be followed by one space. (Example shown below.)\n\n```markdown\n- osu!\n  - Hit circle\n    - Combo number\n    - Approach circle\n  - Slider\n    - Hit circles\n    - Slider body\n    - Slider ticks\n  - Spinner\n- osu!taiko\n```\n\n### Numbered\n\nThe numbers in a numbered list must be incremented to represent their step.\n\n```markdown\n1. Download the osu! installer.\n2. Run the installer.\n   1. To change the installation location, click the text underneath the progression bar.\n   2. The installer will prompt for a new location, choose the installation folder.\n3. osu! will start up once installation is complete.\n4. Sign in.\n```\n\n### Mixed\n\nCombining both bulleted and numbered lists should be done sparingly.\n\n```markdown\n1. Download a skin from the forums.\n2. Load the skin file into osu!.\n   - If the file is a `.zip`, unzip it and move the contents into the `Skins/` folder (found in your osu! installation folder).\n   - If the file is a `.osk`, open it on your desktop or drag-and-drop it into the game client.\n3. Open osu!, if it is not opened, and select the skin in the options.\n   - This may have been completed if you opened the `.osk` file or drag-and-dropped it into the game client.\n```\n\n## Code\n\nThe markup for code is a grave mark (`` ` ``). To put grave marks in code, use double grave marks instead. If the grave mark is at the start or end, pad it with one space. (Example shown below.)\n\n```markdown\n`` ` ``\n`` `Space` ``\n```\n\n### Keyboard keys\n\n*Notice: When denoting the letter itself, and not the keyboard key, use quotation marks instead.*\n\nWhen representing keyboard keys, use capital letters for single characters and title case for modifiers. Use the plus symbol (`+`) (without code) to represent key combinations. (Example shown below.)\n\n```markdown\npippi is spelt with a lowercase \"p\" like peppy.\n\nPress `Ctrl` + `O` to open the open dialog.\n```\n\nWhen representing a space or the spacebar, use `` `Space` ``.\n\n### Button and menu text\n\nWhen copying the text from a menu or button, the letter casing should be copied as it appears. (Example shown below.)\n\n```markdown\nThe `osu!direct` button is visible in the main menu on the right side, if you have an active osu!supporter tag.\n```\n\n### Folder and directory names\n\nWhen copying the name of a folder or directory, the letter casing should be copied as it appears, but prefer lowercased paths when possible. Directory paths must not be absolute (i.e. do not start the directory name from the drive letter or from the root folder). (Example shown below.)\n\n```markdown\nosu! is installed in the `AppData/Local` folder by default, unless specified otherwise during installation.\n```\n\n### Keywords and commands\n\nWhen copying a keyword or command, the letter casing should be copied as it appears or how someone normally would type it. If applicable, prefer lowercase letters. (Example shown below.)\n\n```markdown\nAs of now, the `Name` and `Author` commands in the skin configuration file (`skin.ini`) do nothing.\n```\n\n### File names\n\nWhen copying the name of a file, the letter casing should be copied as it appears. If applicable, prefer lowercase letters. (Example shown below.)\n\n```markdown\nTo play osu!, double click the `osu!.exe` icon.\n```\n\n### File extensions\n\n*Notice: File formats (not to be confused with file extensions) must be written in capital letters without the prefixed fullstop (`.`).*\n\nFile extensions must be prefixed with a fullstop (`.`) and be followed by the file extension in lowercase letters. (Example shown below.)\n\n```markdown\nThe JPG (or JPEG) file format has the `.jpg` (or `.jpeg`) extension.\n```\n\n### Chat channels\n\nWhen copying the name of a chat channel, start it with a hash (`#`), followed by the channel name in lowercase letters. (Example shown below.)\n\n```markdown\n`#lobby` is where you can advertise your multi room.\n```\n\n## Preformatted text (code blocks)\n\n*Notice: Syntax highlighting for preformatted text is not implemented on the website yet.*\n\nPreformatted text (also known as code blocks) must be fenced using three grave marks. They should set the language identifier for syntax highlighting.\n\n## Links\n\nThere are two types of links: inline and reference. Inline has two styles.\n\nThe following is an example of both inline styles:\n\n```markdown\n[Game Modifiers](/wiki/Game_Modifiers)\n\n<https://osu.ppy.sh/home>\n```\n\nThe following is an example of the reference style:\n\n```markdown\n[Game Modifiers][game mods link]\n\n[game mods link]: /wiki/Game_Modifiers\n```\n\n---\n\nLinks must use the inline style if they are only referenced once. The inline angle brackets style should be avoided. References to reference links must be placed at the bottom of the article.\n\n### Internal links\n\n*Note: Internal links refer to links that stay inside the `https://osu.ppy.sh/` domain.*\n\n#### Wiki links\n\nAll links that point to an wiki article should start with `/wiki/` followed by the path to get to the article you are targeting. Relative links may also be used. Some examples include the following:\n\n```markdown\n[FAQ](/wiki/FAQ)\n[pippi](/wiki/Mascots#-pippi)\n[Beatmaps](../)\n[Pattern](./Pattern)\n```\n\nWiki links must not use redirects and must not have a trailing forward slash (`/`).\n\nBad examples include the following:\n\n```markdown\n[Article styling criteria](/wiki/ASC)\n[Developers](/wiki/Developers/)\n[Developers](/wiki/Developers/#game-client-developers)\n```\n\nGood examples include the following:\n\n```markdown\n[Article styling criteria](/wiki/Article_styling_criteria)\n[Developers](/wiki/Developers)\n[Developers](/wiki/Developers#game-client-developers)\n```\n\n##### Sub-article links\n\nWiki links that point to a sub-article should include the parent article's folder name in its link text. See the following example:\n\n```markdown\n*See also: [Beatmap Editor/Design](/wiki/Beatmap_Editor/Design)*\n```\n\n##### Section links\n\n*Notice: On the website, heading levels 4 and 5 are not given the id attribute. This means that they can not be linked to directly.*\n\nWiki links that point to a section of an article may use the section sign symbol (`§`). See the following example:\n\n```markdown\n*For timing rules, see: [Ranking Criteria § Timing](/wiki/Ranking_Criteria#timing)*\n```\n\n#### Other osu! links\n\nThe URL from the address bar of your web browser should be copied as it is when linking to other osu! web pages. The `https://osu.ppy.sh` part of the URL must be kept.\n\n##### User profiles\n\nAll usernames must be linked on first occurrence. Other occurrences are optional, but must be consistent throughout the entire article for all usernames. If it is difficult to determine the user's id, it may be skipped over.\n\nWhen linking to a user profile, the user's id number must be used. Use the new website (`https://osu.ppy.sh/users/{username})`) to get the user's id.\n\nThe link text of the user link should be the user's current name.\n\n##### Difficulties\n\nWhenever linking to a single difficulty, use this format as the link text:\n\n```\n{artist} - {title} ({creator}) [{difficuty_name}]\n```\n\nThe link must actually link to that difficulty. Beatmap difficulty URLs must be formatted as follows:\n\n```\nhttps://osu.ppy.sh/beatmapsets/{BeatmapSetID}#{mode}/{BeatmapID}\n```\n\nThe difficulty name may be left outside of the link text, but doing so must be consistent throughout the entire article.\n\n##### Beatmaps\n\nWhenever linking to a beatmap, use this format as the link text:\n\n```\n{artist} - {title} ({creator})\n```\n\nAll beatmap URLs must be formatted as follows:\n\n```\nhttps://osu.ppy.sh/beatmapsets/{BeatmapSetID}\n```\n\n### External links\n\n*Notice: External links refers to links that go outside the `https://osu.ppy.sh/` domain.*\n\nThe `https` protocol must be used, unless the site does not support it. External links must be a clean and direct link to a reputable source. The link text should be the title of the page it is linking to. The URL from the address bar of your web browser should be copied as it is when linking to other external pages.\n\nThere are no visual differences between external and osu! web links. Due to this, the website name should be included in the title text. See the following example:\n\n```markdown\n*For more information about music theory, see: [Music theory](https://en.wikipedia.org/wiki/Music_theory \"Wikipedia\")*\n```\n\n## Images\n\nThere are two types of image links: inline and reference. Examples:\n\n**Inline style:**\n\n```markdown\n![](/wiki/shared/flag/AU.gif)\n```\n\n**Reference style:**\n\n```markdown\n![][flag_AU]\n\n[flag_AU]: /wiki/shared/flag/AU.gif\n```\n\nImages should use the inline linking style. References to reference links must be placed at the bottom of the article.\n\nImages must be placed in a folder named `img`, located in the article's folder. Images that are used in multiple articles should be stored in the `/wiki/shared/` folder.\n\n### Image caching\n\nImages on the website are cached for up to 60 days. The cached image is matched with the image link's URL.\n\nWhen updating an image, either change the image's name or append a query string to the URL. In both cases, all translations linking to the updated image should also be updated.\n\n### Formats and quality\n\nImages should use the JPG format at quality 8 (80 or 80%, depending on the program). If the image contains transparency or has text that must be readable, use the PNG format instead. If the image contains an animation, the GIF format can be used; however, this should be used sparingly as these may take longer to load or can be bigger then the [max file size](#file-size).\n\n### File size\n\nImages must be under 1 megabyte, otherwise they will fail to load. Downscaling and using JPG at 80% is almost always under the size limit.\n\nAll images should be optimised as much as possible. Use [jpeg-archive](https://github.com/danielgtaylor/jpeg-archive \"GitHub\") to compress JPEG images. For consistency, use the following command for jpeg-archive:\n\n```sh\njpeg-recompress -am smallfry <input> <output>\n```\n\nWhere `<input>` is the file name to be compressed and `<output>` is the compressed file name.\n\n### File names\n\n*Notice: File extensions must use lowercase letters, otherwise they will fail to load!*\n\nUse hyphens (`-`) when spacing words. When naming an image, the file name should be meaningful or descriptive but short.\n\n### Formatting and positioning\n\n*Note: It is currently not possible to float an image or have text wrap around it.*\n\nImages on the website will be centred when it is on a single line, by themself. Otherwise, they will be positioned inline with the paragraph. The following example will place the image in the center:\n\n```markdown\nInstalling osu! is easy. First, download the installer from the download page.\n\n![](img/download-page.jpg)\n\nThen locate the installer and run it.\n```\n\n### Alt text\n\nImages should have alt text unless it is for decorative purposes.\n\n### Captions\n\nImages are given captions on the website if they fulfill these conditions:\n\n1. The image is by itself.\n2. The image is not inside a heading.\n3. The image has title text.\n\nCaptions are assumed via the title text, which must be in plain text. Images with captions are also centred with the image on the website.\n\n### Max image width\n\nThe website's max image width is the width of the article body. Images should be no wider than 800 pixels.\n\n### Annotating images\n\nWhen annotating images, use *Torus Regular*. For Chinese, Korean, Japanese characters, use *Microsoft YaHei*.\n\nAnnotating images should be avoided, as it is difficult for translators (and other editors) to edit them.\n\n#### Translating annotated images\n\nWhen translating annotated images, the localised image version must be placed in the same directory as the original version (i.e. the English version). The filename of a localised image version must start with the original version's name, followed by a hyphen, followed by the locale name (in capital letters). See the following examples:\n\n- `hardrock-mod-vs-easy-mod.jpg` for English\n- `hardrock-mod-vs-easy-mod-DE.jpg` for German\n- `hardrock-mod-vs-easy-mod-ZH-TW.jpg` for Traditional Chinese\n\n### Screenshots of gameplay\n\nAll screenshots of gameplay must be done in the stable build, unless it is for a specific feature that is unavailable in the stable build. You should use the in-game screenshot feature (`F12`).\n\n#### Game client settings\n\n*Note: If you do not want to change your current settings for the wiki, you can move your `osu!.<ComputerUser>.cfg` out of the osu! folder and move it back later.*\n\nYou must set these settings before taking a screenshot of the game client (settings not stated below are assumed to be at their defaults):\n\n- Select language: `English`\n- Prefer metadata in original language: `Enabled`\n- Resolution: `1280x720`\n- Fullscreen mode: `Disabled`\n- Parallax: `Disabled`\n- Menu tips: `Disabled`\n- Seasonal backgrounds: `Never`\n- Always show key overlay: `Enabled`\n- Current skin: `Default` (first option)\n\n*Notice to translators: If you are translating an article containing screenshots of the game, you may set the game client's language to the language you are translating in.*\n\n### Image links\n\nImages must not be part of a link text.\n\nFlag icons next to user links must be separate from the link text. See the following example:\n\n```markdown\n![][flag_AU] [peppy](https://osu.ppy.sh/users/2)\n```\n\n### Flag icons\n\n*For a list of flag icons, see: [issue \\#328](https://github.com/ppy/osu-wiki/issues/328 \"GitHub\")*\n\nThe flag icons use the two letter code (in all capital letters) and end with `.gif`. When adding a flag inline, use this format:\n\n```markdown\n![](/wiki/shared/flag/xx.gif)\n```\n\nWhere `xx` is the [ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 \"Wikipedia\") two-lettered country code for the flag.\n\nThe full country name should be added in the title text. The country code in the alternate text is optional, but must be applied to all flag icons in the article.\n\n## Tables\n\nTables on the website only support headings along the first row.\n\nTables must not be beautified (do not pad cells with extra spaces to make their widths uniform). They must have a vertical bar (`|`) on the left and right sides and the text of each cell must be padded with one space on both sides. Empty cells must use a vertical bar (`|`) followed by two spaces then another vertical bar (`|`).\n\nThe delimiter row (the next line after the table heading) must use only three characters per column (and be padded with a space on both sides), which must look like one of the following:\n\n- `:--` (for left align)\n- `:-:` (for centre align)\n- `--:` (for right align)\n\n---\n\nThe following is an example of what a table should look like:\n\n```markdown\n| Team \"Picturesque\" Red | Score | Team \"Statuesque\" Blue | Average Beatmap Stars |\n| :-- | :-: | --: | :-- |\n| **peppy** | 5 - 2 | pippi | 9.3 stars |\n| Aiko | 1 - 6 | **Alisa** | 4.2 stars |\n| Ryūta | 3 - 4 | **Yuzu** | 5.1 stars |\n| **Taikonator** | 7 - 0 | Tama | 13.37 stars |\n| Maria | No Contest | Mocha |  |\n```\n\n## Blockquotes\n\nThe blockquote is limited to quoting text from someone. It must not be used to format text otherwise.\n\n## Thematic breaks\n\nThe thematic break (also known as the horizontal rule or line) should be used sparingly. A few uses of the thematic break may include (but is not limited to):\n\n- separating images from text\n- separating multiple images that follow one another\n- shifting the topic within a section\n\nThese must have an empty line before and after the markup. Thematic breaks must use only three hyphens, as depicted below:\n\n```markdown\n---\n```\n"
        };
    }
}
